package com.haibara.codesandbox.threadPool;

import com.github.dockerjava.api.command.CreateContainerResponse;
import com.haibara.codesandbox.core.CodeSandboxTemplate;
import com.haibara.codesandbox.model.QuestionCase;
import com.haibara.codesandbox.model.ResultMessage;
import com.haibara.codesandbox.model.RunCodeResult;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.*;

import static com.haibara.codesandbox.core.DefaultCodeSandbox.TIME_EXCEED;

/**
 * @Author: mengyu
 * @Date: 2025/6/5
 */
@Component
@Slf4j
public class RunCodeTask {
    @Resource
    private CodeSandboxTemplate defaultCodeSandbox;
    @Resource
    private ThreadPoolConfig threadPoolConfig;

    private ThreadPoolExecutor threadPool;

    @PostConstruct
    private void initThreadPool() {
        threadPool = new ThreadPoolExecutor(
                threadPoolConfig.getCore(), // 核心线程数
                threadPoolConfig.getMax(), // 最大线程数
                60L,
                TimeUnit.SECONDS, // 空闲线程存活时间
                new ArrayBlockingQueue<>(threadPoolConfig.getQueueSize()), // 等待队列
                Executors.defaultThreadFactory(), // 线程工厂
                new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
        );
    }

    public CompletableFuture<RunCodeResult> createTask(CreateContainerResponse container,
                                                       QuestionCase questionCase,
                                                       Long userId,
                                                       Long questionId,
                                                       Integer timeLimit,
                                                       Long questionSubmitId) {
        log.info("创建执行代码任务 questionSubmitId:{}, questionCaseId:{}", questionSubmitId, questionCase.getId());
        return CompletableFuture.supplyAsync(
                        () -> {
                            try {
                                return defaultCodeSandbox.runCode(container, questionCase, userId, questionId, questionSubmitId, timeLimit);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }, threadPool
                )
                .handle(
                        (result, ex) -> {
                            // 处理异常和结果
                            if (ex == null) {
                                return result;
                            } else {
                                // 系统异常
                                log.error("运行代码发生异常: userId={}, questionId={}, questionSubmitId={}, msg:{}", userId, questionId, questionSubmitId, ex.getMessage());
                                throw new RuntimeException(ex);
                            }
                        }
                );
    }
}
